package com.yeyks.appcontroller;

import com.alibaba.fastjson.JSONObject;
import com.yeyks.base.Arguments;
import com.yeyks.constant.ConfigKey;
import com.yeyks.dal.domain.UserInfo;
import com.yeyks.exception.ServiceException;
import com.yeyks.model.Ajax.AjaxResponseBody;
import com.yeyks.model.PreOrderType;
import com.yeyks.service.*;
import com.yeyks.util.Utility;
import com.yeyks.service.ConfigService;
import com.yeyks.wxpay.impl.MyConfig;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author fuchangshuai
 * @date 2019/3/26 5:06 PM
 */
@Api(tags = "vip订单接口", description = "vip订单")
@Slf4j
@RestController("appVipOrderController")
@RequestMapping(value = "/app/vip/order")
public class VipOrderController {

    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private VipOrderService vipOrderService;
    @Autowired
    private ConfigService configService;
    @Autowired
    private PayService payService;

    /**
     * 用户充值
     *
     * @return
     */
    @ApiOperation(value = "用户充值", notes = "用户充值")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "token", value = "token", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "price", value = "充值金额", required = true, dataType = "int"),
            @ApiImplicitParam(paramType = "query", name = "inviteId", value = "邀请码", dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "type", value = "支付类型（wxpay,alipay）", required = true, dataType = "String")
    })
    @PostMapping(value = "/pay")
    public ResponseEntity<?> vipPay(@RequestParam(name = "token") String token,
                                    @RequestParam(name = "price") Integer price,
                                    @RequestParam(name = "inviteId", required = false) String inviteId,
                                    @RequestParam(name = "type") String type,
                                    HttpServletRequest request) {
        UserInfo userInfo = userInfoService.tokenUserInfo(token);
        Map<String, String> map = vipOrderService.vipPay(userInfo, inviteId, price, type, Utility.getRemoteIP(request));
        return ResponseEntity.ok(AjaxResponseBody.success(map));
    }

    /**
     * h5用户充值
     *
     * @param token
     * @param code       code
     * @param sourceType
     * @return
     */
    @ApiOperation(value = "h5用户充值", notes = "当获取不到openid时code必传")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "token", value = "token", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "code", value = "code", dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "price", value = "充值金额", required = true, dataType = "int"),
            @ApiImplicitParam(paramType = "query", name = "inviteId", value = "邀请码", dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "sourceType", value = "sourceType", defaultValue = "wx", dataType = "String")
    })
    @RequestMapping(value = "/h5/Pay", method = RequestMethod.POST)
    public ResponseEntity<?> h5VipPay(@RequestParam(name = "token") String token,
                                      @RequestParam(name = "code", required = false) String code,
                                      @RequestParam(name = "price") Integer price,
                                      @RequestParam(name = "inviteId", required = false) String inviteId,
                                      @RequestParam(name = "sourceType", defaultValue = "wx") String sourceType,
                                      HttpServletRequest request) {
        int orderType = PreOrderType.parse(sourceType);
        //true代表是公众号，false代表小程序
        boolean flag = orderType == PreOrderType.wx || orderType == PreOrderType.h5;
        String type = "xcx";
        if (flag) {
            type = "gzh";
        }
        UserInfo userInfo = userInfoService.tokenUserInfo(token);
        //检测是否该用户是否有openid
        String openId = checkOpenid(userInfo, code, flag);
        String ip = Utility.getRemoteIP(request);
        Map<String, Object> map = vipOrderService.h5VipPay(userInfo, inviteId, price, type, ip, openId, flag);
        return ResponseEntity.ok(AjaxResponseBody.success(map));
    }

    /**
     * 充值取消后去支付
     *
     * @param token
     * @param orderNo 订单号
     * @param type    支付方式
     * @return
     */
    @ApiIgnore
    @ApiOperation(value = "充值取消后去支付", notes = "充值取消后去支付")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "token", value = "token", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "orderNo", value = "订单号", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query", name = "type", value = "支付类型（wxpay,alipay）", required = true, dataType = "String")
    })
    @RequestMapping(value = "/goPay", method = RequestMethod.POST)
    public ResponseEntity<?> vipGoPay(@RequestParam(name = "token") String token,
                                      @RequestParam(name = "orderNo") String orderNo,
                                      @RequestParam(name = "type") String type,
                                      HttpServletRequest request) {
        checkParamOrderNo(orderNo);
        UserInfo userInfo = userInfoService.tokenUserInfo(token);
        String ip = Utility.getRemoteIP(request);
        Map<String, String> map = vipOrderService.goPay(userInfo, orderNo, type, ip);
        return ResponseEntity.ok(AjaxResponseBody.success(map));
    }

    /**
     * 获取充值链接
     *
     * @return
     */
    @ApiOperation(value = "获取充值链接", notes = "获取充值链接")
    @RequestMapping(value = "/pay/url", method = RequestMethod.POST)
    public ResponseEntity<?> payUrl() {
        String value = configService.getValue(ConfigKey.PAY_URL);
        return ResponseEntity.ok(AjaxResponseBody.success(value));
    }

    private void checkParamOrderNo(String orderNo) {
        if (Arguments.isEmpty(orderNo)) {
            throw new ServiceException("订单号不能为空");
        }
    }

    private String checkOpenid(UserInfo userInfo, String code, Boolean flag) {
        JSONObject jsonObject = JSONObject.parseObject(userInfo.getExtraInfo());
        //公众号
        if (flag) {
            String gzhOpenId = null;
            if (jsonObject != null) {
                gzhOpenId = (String) jsonObject.get("gzhOpenId");
            }
            if (gzhOpenId != null) {
                return gzhOpenId;
            }
            if (!Arguments.notEmpty(code)) {
                throw new ServiceException("openid为空");
            }
            try {
                MyConfig config = new MyConfig();
                Utility.switchConfig(true, null, config);
                JSONObject jsonObjectv2 = payService.wxParseCode(true, code, config);
                gzhOpenId = jsonObjectv2.get("openid").toString();
            } catch (Throwable e) {
                log.info("获取xcxOpenId失败{}", code);
                throw new ServiceException("获取公众号OpenId失败");
            }
            Map<String, Object> map = new HashMap<>();
            map.put("gzhOpenId", gzhOpenId);
            if (jsonObject != null) {
                String xcxOpenId = (String) jsonObject.get("xcxOpenId");
                if (Arguments.notEmpty(xcxOpenId)) {
                    map.put("xcxOpenId", xcxOpenId);
                }
            }
            userInfo.setExtraInfo(JSONObject.toJSONString(map));
            Integer res = userInfoService.updateExtraInfoById(userInfo.getId(), userInfo.getExtraInfo());
            if (res != 1) {
                throw new ServiceException("更新openid失败");
            }
            return gzhOpenId;
        }
        String xcxOpenId = null;
        if (jsonObject != null) {
            xcxOpenId = (String) jsonObject.get("xcxOpenId");
        }
        if (xcxOpenId != null) {
            return xcxOpenId;
        }
        if (!Arguments.notEmpty(code)) {
            throw new ServiceException("openid为空");
        }
        try {
            MyConfig config = new MyConfig();
            Utility.switchConfig(flag, null, config);
            JSONObject jsonObjectv2 = payService.wxParseCode(flag, code, config);
            xcxOpenId = jsonObjectv2.get("openid").toString();
        } catch (Throwable e) {
            log.info("获取xcxOpenId失败{}", code);
            throw new ServiceException("获取小程序OpenId失败");
        }
        Map<String, Object> map = new HashMap<>();
        map.put("xcxOpenId", xcxOpenId);
        if (jsonObject != null) {
            String gzhOpenId = (String) jsonObject.get("gzhOpenId");
            if (Arguments.notEmpty(gzhOpenId)) {
                map.put("gzhOpenId", gzhOpenId);
            }
        }
        userInfo.setExtraInfo(JSONObject.toJSONString(map));
        Integer res = userInfoService.updateExtraInfoById(userInfo.getId(), userInfo.getExtraInfo());
        if (res != 1) {
            throw new ServiceException("更新openid失败");
        }
        return xcxOpenId;
    }
}
